package com.quanquan.store.service;

import DTO.store.StoreDTO;
import DTO.store.StoreInfoDTO;
import DTO.user.UserDTO;
import DTO.user.UserInfoDTO;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.quanquan.store.dto.DailyReportDTO;
import com.quanquan.store.dto.IdDTO;
import com.quanquan.store.dto.NoSupportStoreDTO;
import com.quanquan.store.dto.ReportDTO;
import com.quanquan.store.entity.Admin;
import com.quanquan.store.entity.DailyReport;
import com.quanquan.store.entity.Store;
import com.quanquan.store.repository.DailyReportRepository;
import com.quanquan.store.repository.StoreRepository;
import com.quanquan.store.request.DailyReportRequestBody;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.internal.Function;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import utils.DateUtils;
import utils.StringUtil;
import utils.UUIDGenerator;

import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 功能描述:每日报表逻辑层
 *
 * @ClassName: DailyReportService
 * @Author: xiaoqianh丶
 * @Date: 2019-07-02 10:28
 * @Version: V1.0
 */
@Service
public class DailyReportService {

    private final DailyReportRepository dailyReportRepository;

    private final RestTemplate restTemplate;


    private final AdminService adminService;
    @Autowired
    private StoreRepository storeRepository;

    public DailyReportService(DailyReportRepository dailyReportRepository, RestTemplate restTemplate, AdminService adminService) {
        this.dailyReportRepository = dailyReportRepository;
        this.restTemplate = restTemplate;
        this.adminService = adminService;
    }

    public String createDailyReport(DailyReportRequestBody requestBody) {
        DailyReport dailyReport = dailyReportRepository.findByStoreIdAndDateTime(requestBody.getStoreId(), requestBody.getCreateTime());
        if (dailyReport == null) {
            dailyReport = new DailyReport();
            dailyReport.setId(UUIDGenerator.getUUID());
            //通过映射关系来赋值 //TODO 断点看一下
            BeanUtils.copyProperties(requestBody, dailyReport);
            Store store = storeRepository.findByStoreId1(requestBody.getStoreId());
            dailyReport.setStoreName(store.getStoreName());
            dailyReport.setRemove(0);
            dailyReportRepository.save(dailyReport);
            return "提交成功";
        } else {
            return null;
        }
    }


    /**
     * 后端展示每日提交数据
     *
     * @param requestBody
     * @return
     */
    public ReportDTO findAllDailyReport(DailyReportRequestBody requestBody) {
        ReportDTO reportDTO = new ReportDTO();
        Integer page = null == requestBody.getPage() ? 0 : requestBody.getPage();
        Integer size = null == requestBody.getSize() ? 10 : requestBody.getSize();
        String storeId = requestBody.getStoreId();
        String to = requestBody.getToDate();
        String from = requestBody.getFromDate();
        String keyword = requestBody.getKeyword();
        String storeName = requestBody.getStoreName();
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(page, size, sort);

        Page<DailyReport> paged = dailyReportRepository.findAll((Specification<DailyReport>) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (StringUtil.isNotEmpty(keyword)) {
                IdDTO idDTO = new IdDTO();
                idDTO.setKeyWord(keyword);
                UserInfoDTO userInfoDTO = restTemplate.postForObject("http://QUANQUAN-USER/user/query_keyword", idDTO, UserInfoDTO.class);
                if (userInfoDTO != null) {
                    List<UserDTO> users = userInfoDTO.getUserDTOS();
                    if (users.size() > 0) {
                        DTO.user.UserDTO userDTO = users.get(0);
                        predicates.add(cb.equal(root.get("userId").as(String.class), userDTO.getId()));
                    }
                }
            }

            if (StringUtil.isNotEmpty(storeId)) {
                predicates.add(cb.equal(root.get("storeId").as(String.class), storeId));
            }

            if (StringUtil.isNotEmpty(storeName)) {
                predicates.add(cb.like(root.get("storeName").as(String.class), "%" + storeName + "%"));
            }

            if (StringUtil.isNotEmpty(from)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(from, DateUtils.DATE));

                predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(to)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(to, DateUtils.DATE));
                predicates.add(cb.lessThanOrEqualTo(root.get("createTime").as(Date.class), endOfDay));
            }
            predicates.add(cb.equal(root.get("remove").as(Integer.class), 0));
            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);

        //拿到storeId
        List<DailyReport> dailyReportList = paged.getContent();

        List<DailyReport> dailyReportList1;


        /*double totalMoney = dailyReportList.stream().mapToDouble(DailyReport::getTradingTotalNum).sum();

        //计算总笔数和总金额
        int tradingNumTotal = dailyReportList.parallelStream().mapToInt(DailyReport::getTradingNum).sum();*/
        int tradingNumTotal = 0;
        String totalMoney = "0.0";
        if (StringUtil.isNotEmpty(storeId)) {
            dailyReportList1 = dailyReportRepository.findByStoreId(storeId);
        } else {
            dailyReportList1 = dailyReportRepository.findAlls();
        }
        if (dailyReportList1.size() <= 0) {
            totalMoney = "0.0";
            tradingNumTotal = 0;
        }else {
            for (DailyReport dailyReport : dailyReportList1) {
                BigDecimal totalMoney2 = new BigDecimal(totalMoney);
                BigDecimal getTradingTotalNum = new BigDecimal(Double.toString(dailyReport.getTradingTotalNum()));
                NumberFormat nf = NumberFormat.getInstance();
                //设置保留多少位小数
                nf.setMaximumFractionDigits(2);
                // 取消科学计数法
                nf.setGroupingUsed(false);
                totalMoney = nf.format(totalMoney2.add(getTradingTotalNum).doubleValue());
                tradingNumTotal = tradingNumTotal + dailyReport.getTradingNum();

            }
        }
        List<DailyReportDTO> dailyReportDTOS = new ArrayList<>();
        for (DailyReport dailyReport : dailyReportList) {
            DailyReportDTO dailyReportDTO = new DailyReportDTO();
            //通过映射关系来赋值 //TODO 断点看一下
            BeanUtils.copyProperties(dailyReport, dailyReportDTO);
            dailyReportDTOS.add(dailyReportDTO);
        }

        List<String> storeIds = dailyReportList.parallelStream().filter(distinctByKey(DailyReport::getStoreId)).map(DailyReport::getStoreId).collect(Collectors.toList());
        //拿到userID
        List<String> userIds = dailyReportList.parallelStream().filter(distinctByKey(DailyReport::getUserId)).map(DailyReport::getUserId).collect(Collectors.toList());
        //商铺实体
        IdDTO idDTO = new IdDTO();
        idDTO.setForeignKeyIds(storeIds);

        StoreInfoDTO storeInfoDTO = restTemplate.postForObject("http://QUANQUAN-STORE/store/query_by_id_list", idDTO, StoreInfoDTO.class);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();


        for (DailyReportDTO dailyReportDTO : dailyReportDTOS) {
            for (StoreDTO storeDTO : storeDTOS) {
                if (storeDTO.getId().equals(dailyReportDTO.getStoreId())) {
                    dailyReportDTO.setStoreName(storeDTO.getStoreName());
                    dailyReportDTO.setStoreCommercial(storeDTO.getStoreCommercial());
                }
            }

        }


        List<Admin> admins = adminService.findAdminById(userIds);


        //用户实体
        for (DailyReportDTO dailyReportDTO : dailyReportDTOS) {
            for (Admin admin : admins) {
                if (admin.getId().equals(dailyReportDTO.getUserId())) {

                    dailyReportDTO.setMemberName(admin.getName());
                }
            }

        }
        reportDTO.setPage(page);
        reportDTO.setSize(size);
        reportDTO.setTotal(paged.getTotalElements());
        reportDTO.setDailyReportDTOS(dailyReportDTOS);
        reportDTO.setTotalMoney(totalMoney);
        reportDTO.setTradingNumTotal(tradingNumTotal);
        return reportDTO;

    }

    private static <T> java.util.function.Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

    public String updateDailyReport(DailyReportRequestBody requestBody) {
        String dailyReportId = requestBody.getDailyReportId();
        DailyReport dailyReport = dailyReportRepository.findByIdAndRemove(dailyReportId, 0);
        BeanUtil.copyProperties(requestBody, dailyReport, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        dailyReportRepository.saveAndFlush(dailyReport);
        return "修改成功";
    }

    /**
     * 根据id查询详情
     *
     * @param dailyReportId
     */
    public DailyReportDTO queryDetails(String dailyReportId) {
        DailyReportDTO dailyReportDTO = new DailyReportDTO();
        DailyReport dailyReport = dailyReportRepository.findByIdAndRemove(dailyReportId, 0);

        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtils.copyProperties(dailyReport, dailyReportDTO);
        String storeId = dailyReport.getStoreId();
        String userId = dailyReport.getUserId();
        List<String> storeIds = new ArrayList<>();
        storeIds.add(storeId);
        List<String> userIds = new ArrayList<>();
        userIds.add(userId);
        //商铺实体
        IdDTO idDTO = new IdDTO();
        idDTO.setForeignKeyIds(storeIds);

        StoreInfoDTO storeInfoDTO = restTemplate.postForObject("http://QUANQUAN-STORE/store/query_by_id_list", idDTO, StoreInfoDTO.class);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();
        if (storeDTOS.size() > 0) {
            StoreDTO storeDTO = storeDTOS.get(0);
            dailyReportDTO.setStoreCommercial(storeDTO.getStoreCommercial());
            dailyReportDTO.setStoreName(storeDTO.getStoreName());
        }

        //用户实体

        List<Admin> admins = adminService.findAdminById(userIds);

        if (admins.size() > 0) {
            Admin admin = admins.get(0);
            dailyReportDTO.setMemberName(admin.getName());
        }
        return dailyReportDTO;
    }


    /**
     * 查看未提报商户列表
     *
     * @param requestBody
     * @return
     */
    public List<NoSupportStoreDTO> queryDailyStore(DailyReportRequestBody requestBody) {
        Integer page = requestBody.getPage() == null ? 0 : requestBody.getPage();
        Integer size = requestBody.getSize() == null ? 30 : requestBody.getSize();
        //今天未提报商户列表
        List<String> storeNameToday = dailyReportRepository.findByStoreNoSupport(0);
        //昨天未提报商户列表
        List<String> storeNameYday = dailyReportRepository.findByStoreNoSupport(1);
        //前天未提报商户列表
        List<String> storeNameTDBY = dailyReportRepository.findByStoreNoSupport(2);
        //将所有数据加入到新的集合中
        List<NoSupportStoreDTO> allStore = new LinkedList<>();
        for (String name : storeNameToday) {
            NoSupportStoreDTO noSupportStoreDTO = new NoSupportStoreDTO();
            noSupportStoreDTO.setStoreName(name);
            noSupportStoreDTO.setDayTime(DateUtils.dateToString(new Date(), "yyyy-MM-dd"));
            allStore.add(noSupportStoreDTO);
        }
        for (String name : storeNameYday) {
            NoSupportStoreDTO noSupportStoreDTO = new NoSupportStoreDTO();
            noSupportStoreDTO.setStoreName(name);
            noSupportStoreDTO.setDayTime(DateUtils.getDate(1));
            allStore.add(noSupportStoreDTO);
        }
        for (String name : storeNameTDBY) {
            NoSupportStoreDTO noSupportStoreDTO = new NoSupportStoreDTO();
            noSupportStoreDTO.setStoreName(name);
            noSupportStoreDTO.setDayTime(DateUtils.getDate(2));
            allStore.add(noSupportStoreDTO);
        }
        Comparator<NoSupportStoreDTO> getStoreName = Comparator.comparing(NoSupportStoreDTO::getStoreName);//按照StoreName升序
        Comparator<NoSupportStoreDTO> getDayTime = Comparator.comparing(NoSupportStoreDTO::getDayTime);//按照DayTime升序
        Collections.sort(allStore, getStoreName.thenComparing(getDayTime));
        if (page == 0 && size < allStore.size()) {
            return allStore.subList(size * page, size * (page + 1));
        }
        if (page == 0 && size > allStore.size()) {
            return allStore.subList(size * page, allStore.size());
        }
        if (size * page < 0) {
            return new LinkedList<>();
        }
        if (allStore.size() - size * page < 0) {
            return new LinkedList<>();
        }
        if (allStore.size() - size * page < size) {
            return allStore.subList(size * page, allStore.size());
        }
        return allStore.subList(size * page, size * (page + 1));
    }


 /*   public static void main(String[] args) {
        double a = 9999999.0;
        double b = 13323.0;
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        NumberFormat nf = NumberFormat.getInstance();
        //设置保留多少位小数
        nf.setMaximumFractionDigits(2);
        // 取消科学计数法
        nf.setGroupingUsed(false);
        nf.format(b1.add(b2).doubleValue())
        System.out.println(nf.format(b1.add(b2).doubleValue()));
    }*/

}
